﻿using StockMatch.Service.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Titan;

namespace StockMatch.Service
{
    [RolePower]
    public class UserService : ContextBoundObject
    {

        #region 增删改
        
        public bool Insert(User user) {
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    if (IsExistUserName(user.UserName))
                    {
                        throw new StockException("此用户名已存在");
                    }
                    if (IsExistEmai(user.Email))
                    {
                        throw new StockException("此邮箱已存在");
                    }
                    if (IsExistUserPhone(user.Phone))
                    {
                        throw new StockException("此手机号已存在");
                    }
                    return cn.Insert(user) > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }
        
        public bool Update(User user,params object[] updateProperty)
        {
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    if (IsExistUserName(user.UserName, user.UserId)) {
                        throw new StockException("此用户名已存在");
                    }
                    if (IsExistEmai(user.Email, user.UserId))
                    {
                        throw new StockException("此邮箱已存在");
                    }
                    if (IsExistUserPhone(user.Phone, user.UserId))
                    {
                        throw new StockException("此手机号已存在");
                    }
                    return cn.Update(user,updateProperty) > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex);
            }
        }

        public bool Delete(int userId) {
            try
            {
                using (var cn=Environment.OpenSession())
                {
                    var user = new User() { UserId=userId};
                    return cn.Delete(user)>0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        #endregion


        #region 查询

        public User GetUser(int userId) {
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var user = new User() {UserId = userId};
                    if (cn.Select(user))
                    {
                        return user;
                    }
                    return null;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        /// <summary>
        /// 根据用户名查询
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool IsExistUserName(string userName, int userId)
        {
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var query = new QueryExpression();
                    query.EntityType = typeof (User);
                    query.Select(User_.UserId);
                    query.Wheres.Add(User_.UserName.TEqual(userName));
                    query.Wheres.Add(User_.UserId.TNotEqual(userId));

                    var users = new Users();
                    cn.SelectCollection(users.Items, query);
                    return users.Items.Count > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        public bool IsExistUserName(string userName)
        {
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var query = new QueryExpression();
                    query.EntityType = typeof(User);
                    query.Select(User_.UserId);
                    query.Wheres.Add(User_.UserName.TEqual(userName));
                    var users = new Users();
                    cn.SelectCollection(users.Items, query);
                    return users.Items.Count > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        public bool IsExistUserPhone(string phome, int userId)
        {
            if (string.IsNullOrEmpty(phome))
            {
                return false;
            }
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var query = new QueryExpression();
                    query.EntityType = typeof (User);
                    query.Select(User_.UserId);
                    query.Wheres.Add(User_.Phone.TEqual(phome));
                    query.Wheres.Add(User_.UserId.TNotEqual(userId));

                    var users = new Users();
                    cn.SelectCollection(users.Items, query);
                    return users.Items.Count > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        public bool IsExistUserPhone(string phome)
        {
            if (string.IsNullOrEmpty(phome))
            {
                return false;
            }
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var query = new QueryExpression();
                    query.EntityType = typeof(User);
                    query.Select(User_.UserId);
                    query.Wheres.Add(User_.Phone.TEqual(phome));
                    var users = new Users();
                    cn.SelectCollection(users.Items, query);
                    return users.Items.Count > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        public bool IsExistEmai(string email, int userId)
        {
            if (string.IsNullOrEmpty(email))
            {
                return false;
            }
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var query = new QueryExpression();
                    query.EntityType = typeof (User);
                    query.Select(User_.UserId);
                    query.Wheres.Add(User_.Email.TEqual(email));
                    query.Wheres.Add(User_.UserId.TNotEqual(userId));

                    var users = new Users();
                    cn.SelectCollection(users.Items, query);
                    return users.Items.Count > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        public bool IsExistEmai(string email)
        {
            if (string.IsNullOrEmpty(email))
            {
                return false;
            }
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    var query = new QueryExpression();
                    query.EntityType = typeof(User);
                    query.Select(User_.UserId);
                    query.Wheres.Add(User_.Email.TEqual(email));
                    
                    var users = new Users();
                    cn.SelectCollection(users.Items, query);
                    return users.Items.Count > 0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        public string IsExistUser(string userName)
        {
            QueryExpression query = new QueryExpression();
            query.EntityType = typeof(User);
            query.Selects.Add(User_.UserId);
            query.Selects.Add(User_.UserName);
            query.Selects.Add(User_.UserState);
            query.Wheres.ConditionRelation = ConditionRelation.Or;
            query.Wheres.Add(User_.UserName.TEqual(userName));
            query.Wheres.Add(User_.Phone.TEqual(userName));
            query.Wheres.Add(User_.Email.TEqual(userName));
            Users users = GetUsers(query);
            if (users.Items.Count <= 0)
            {
                return null;
            }
            return users.Items[0].UserName;
        }

        public Users GetUsers(QueryExpression query) {
            try
            {
                using (var cn=Environment.OpenSession())
                {
                    Users users = new Users();
                    users.TotalCount= cn.SelectCollection(users.Items,query);
                    return users;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }

        #endregion

        /// <summary>
        /// 锁定用户
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public bool LockUser(ICondition condition)
        {
            try
            {
                using (var cn = Environment.OpenSession())
                {
                    User user=new User();
                    user.UserState = 3;
                    return cn.BatchUpdate(user, condition, User_.UserState)>0;
                }
            }
            catch (Exception ex)
            {
                throw new StockException(ex.Message);
            }
        }


        //#region 用户登录错误次数和时间的缓存
       private static Dictionary<string,DateTime> dicTime=new Dictionary<string, DateTime>();
       private static Dictionary<string, int> dicError = new Dictionary<string, int>();
        public void CacheUser(string userName)
        {
            if (dicTime.ContainsKey(userName))
            {
                return;
            }
            dicTime.Add(userName,DateTime.Now.AddMinutes(5));
        }

        public void RemoveCacheUser(string userName)
        {
            if (dicTime.ContainsKey(userName))
            {
                dicTime.Remove(userName);
            }
        }

        public int GetTime(string userName)
        {
            if (!dicTime.ContainsKey(userName))
            {
                return 0;
            }
            DateTime time = dicTime[userName];
            TimeSpan ts1 = new TimeSpan(DateTime.Now.Ticks);
            TimeSpan ts2 = new TimeSpan(time.Ticks);
            TimeSpan ts3 = ts1.Subtract(ts2).Duration();
            int result=(int)ts3.TotalMinutes;
            if (result == 0)
            {
              RemoveCacheUser(userName);
            }
            return result;
        }

        public void CacheUserError(string userName)
        {
            if (dicError.ContainsKey(userName))
            {
                dicError[userName]++;
            }
            else
            {
                dicError.Add(userName,1);
            }
        }

        public void RemoveCacheUserError(string userName)
        {
            if (dicError.ContainsKey(userName))
            {
                dicError.Remove(userName);
            }
        }

        public int GetError(string userName)
        {
            if (!dicError.ContainsKey(userName))
            {
                return 0;
            }
            return dicError[userName];
        }

        //#endrgion
    }
}
